/**
 * TRNManterFornecedor.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package transacoes;

import java.io.IOException;
import negocio.pessoas.*;
import persistencia.pessoas.*;
import java.sql.*;
import java.util.ArrayList;
import plagio.postgres.ConnectionPostgres;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class TRNManterFornecedor {

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * Construtor padrao. Responsavel por criar uma transacao para persistencia
     * das seguintes informacoes de um fornecedor: pessoa, endereco e telefones.
     * @throws java.io.IOException
     */
    public TRNManterFornecedor() {
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="METHODS">
    /**
     * Responsavel por criar a estrutura para inserir o objeto
     * @return construtor do objeto a ser inserido
     */
    private static StringBuilder formInsert() throws IOException{
        StringBuilder query = new StringBuilder();
        // Instrucao responsavel por persistir um fornecedor
        PFornecedor forn = new PFornecedor();
        query.append(forn.formInsert() + "\n");

        // Instrucao responsavel por persistir o endereco de um fornecedor
        PEndereco end = new PEndereco();
        query.append(end.formInsert() + "\n");

        // Instrucao responsavel por persistir o telefone de um fornecedor
        PTelefone tel = new PTelefone();
        query.append(tel.formInsert() + "\n");
        return query;
    }

    /**
     * Responsavel por criar a estrutura para atualizar os objetos:
     * Fornecedor, Endereco e Telefone
     * @param f objeto fornecedor a ser atualizado
     * @param e objeto endereco a ser atualizado
     * @param t objeto telefone a ser atualizado
     * @return construtor para atualizacao dos objetos
     */
    private static StringBuilder formUpdate(Fornecedor f, Endereco e, Telefone t)
                                                            throws IOException{
        StringBuilder query = new StringBuilder();
        // Instrucao para atualizacao dos dados de um fornecedor
        PFornecedor forn = new PFornecedor();
        query.append(forn.formUpdate(f) + "\n");

        // Instrucao para atualizacao das informacoes de endereco do fornecedor
        PEndereco end = new PEndereco();
        query.append(end.formUpdate(e) + "\n");

        // Instrucao para atualizacao das informacoes de telefone do fornecedor
        PTelefone tel = new PTelefone();
        query.append(tel.formUpdate(t) + "\n");
        return query;
    }

    /**
     * Responsavel por criar a estrutura para deletar os objetos:
     * Fornecedor, Endereco e Telefone
     * @param f objeto fornecedor a ser atualizado
     * @param e objeto endereco a ser atualizado
     * @param t objeto telefone a ser atualizado
     * @return construtor para delecao dos objetos
     */
    private static StringBuilder formDelete(Fornecedor f, Endereco e, Telefone t)
                                                            throws IOException{
        StringBuilder query = new StringBuilder();
        // Instrucao para deletar os dados de um fornecedor
        PFornecedor forn = new PFornecedor();
        query.append(forn.formDelete(f) + "\n");

        // Instrucao para deletar as informacoes de endereco do fornecedor
        PEndereco end = new PEndereco();
        query.append(end.formDelete(e) + "\n");

        // Instrucao para deletar as informacoes de telefone do fornecedor
        PTelefone tel = new PTelefone();
        query.append(tel.formDelete(t) + "\n");

        return query;
    }

    /**
     * Responsavel por inserir os objetos: Fornecedor, Endereco e Telefone
     * @param f objeto fornecedor a ser inserido
     * @param e objeto endereco a ser inserido
     * @param lstTelefones lista de telefones para insercao
     * @return TRUE se todas as instrucoes tiverem exito FALSE caso contrario
     */
    public static Boolean insert(Fornecedor f, Endereco e,
                          ArrayList<Telefone> lstTelefones) throws SQLException{
        Boolean status = true;

        // Cria uma nova conexao com o banco de dados e desabilita o
        // autocommit da transacao
        ConnectionPostgres conn = new ConnectionPostgres();

        try{
            conn = ConnectionSystem.connectionSystem();
            conn.getConnection().setAutoCommit(false);

            // Recebe as strings de insercao
            String[] insert = formInsert().toString().split("\n");

            // Monta a instrucao para insercao de um fornecedor na base de dados
            PreparedStatement stat;
            stat = conn.getConnection().prepareStatement(insert[0]);
            stat.setString(1, f.getCod_objeto());
            stat.setString(2, f.getNome());
            stat.setString(3, f.getClassName());
            stat.executeUpdate();

            // Monta a instrucao para insercao de um endereco para o fornecedor
            stat = conn.getConnection().prepareStatement(insert[1]);
            stat.setString(1, e.getCod_objeto());
            stat.setString(2, e.getLogradouro());
            stat.setString(3, e.getCidade());
            stat.setInt(4, e.getEstado());
            stat.setInt(5, e.getNumero());
            stat.setString(6, e.getBairro());
            stat.setString(7, e.getComplemento());
            stat.setString(8, e.getCep());
            stat.setString(9, f.getCod_objeto());
            stat.executeUpdate();

            // Monta a instrucao para insercao de um telefone para o fornecedor
            if(lstTelefones != null){
                stat = conn.getConnection().prepareStatement(insert[2]);
                for(Telefone t : lstTelefones){
                    stat.setString(1, t.getCod_objeto());
                    stat.setString(2, t.getNumero());
                    stat.setString(3, f.getCod_objeto());
                    stat.executeUpdate();
                    t.setPessoa(f.getCod_objeto());
                }
            }

            // Acrescenta o cod_objeto do fornecedor aos demais campos
            e.setPessoa(f.getCod_objeto());

            stat.close();
            conn.getConnection().commit();
        }
        catch(Exception ex){
            ex.printStackTrace();
            status = false;
            // Caso ocorra algum erro a conexao e abortada
            conn.getConnection().rollback();
        }
        finally{
            conn.closeConnection();
        }

        return status;
    }

    /**
     * Responsavel para atualizar os objetos: Fornecedor e Endereco
     * @param f objeto fornecedor a ser atualizado
     * @param e objeto endereco a ser atualizado
     * @return TRUE se todas as instrucoes tiverem exito FALSE caso contrario
     */
    public static Boolean update(Fornecedor f, Endereco e) throws SQLException{
        Boolean status = true;

        // Cria uma nova conexao com o banco de dados e desabilita o
        // autocommit da transacao
        ConnectionPostgres conn = new ConnectionPostgres();

        try{
            conn = ConnectionSystem.connectionSystem();
            conn.getConnection().setAutoCommit(false);

            // Recebe as strings de insercao
            String[] update =
                        formUpdate(f, e, new Telefone()).toString().split("\n");

            // Monta a instrucao para insercao de um fornecedor na base de dados
            PreparedStatement stat;
            stat = conn.getConnection().prepareStatement(update[0]);
            stat.executeUpdate();

            // Monta a instrucao para insercao de um endereco para o fornecedor
            stat = conn.getConnection().prepareStatement(update[1]);
            stat.executeUpdate();

            stat.close();
            conn.getConnection().commit();
        }
        catch(Exception ex){
            ex.printStackTrace();
            status = false;
            // Caso ocorra algum erro a conexao e abortada
            conn.getConnection().rollback();
        }
        finally{
            conn.closeConnection();
        }

        return status;
    }

    /**
     * Responsavel por deletar os objetos: Fornecedor, Endereco e Telefone
     * @param f objeto fornecedor a ser deletado
     * @param e objeto endereco a ser deletado
     * @param lstTelefones lista de telefones para delecao
     * @return TRUE se todas as instrucoes tiverem exito FALSE caso contrario
     */
    public static Boolean delete(Fornecedor f, Endereco e,
                          ArrayList<Telefone> lstTelefones) throws SQLException{
        Boolean status = true;

        // Cria uma nova conexao com o banco de dados e desabilita o
        // autocommit da transacao
        ConnectionPostgres conn = new ConnectionPostgres();

        try{
            conn = ConnectionSystem.connectionSystem();
            conn.getConnection().setAutoCommit(false);

            // Recebe as strings de delecao
            String[] delete =
                    formDelete(f, e, new Telefone()).toString().split("\n");

            // Monta a instrucao para delecao de um endereco para o fornecedor
            PreparedStatement stat;
            stat = conn.getConnection().prepareStatement(delete[1]);
            stat.executeUpdate();

            if(lstTelefones != null){
                PTelefone tel = new PTelefone();

                // Monta a instrucao para delecao de um telefone
                for(Telefone t : lstTelefones){
                    String query = tel.formDelete(t);
                    stat = conn.getConnection().prepareStatement(query);
                    stat.executeUpdate();
                }
            }
            // Monta a instrucao para delecao de um fornecedor na base de dados
            stat = conn.getConnection().prepareStatement(delete[0]);
            stat.executeUpdate();

            stat.close();
            conn.getConnection().commit();
        }
        catch(Exception ex){
            ex.printStackTrace();
            status = false;
            // Caso ocorra algum erro a conexao e abortada
            conn.getConnection().rollback();
        }
        finally{
            conn.closeConnection();
        }

        return status;
    }
    //</editor-fold>
}
